<?php
require_once 'common/item.inc';
require_once 'models/lists.inc';
require_once 'models/TMSTypesModel.inc';

/**
 * 
 * @author kras
 * @property TMSTypesModel $TypesModel
 */
abstract class TMSTypeAggregateModel extends TConfigurable implements IListProvider {
	
/**
 * @var TMSTypesModel
 */	
	protected $_ioc_types_model_;
		
	protected abstract function getAggregates(TMSTypeItem $type);
	protected abstract function getAggregate(TMSTypeItem $type,$nm);
	protected abstract function getRawAggregates(TMSTypeItem $type);
	protected abstract function setRawAggregates(TMSTypeItem $type,$meta);
	protected abstract function editData(TMSTypeItem $type);
	protected abstract function parseData($nm,$data);
	

/**
 * @param TListOptions $options
 * @return int
 */
	public function GetCount(TListOptions $options = null){
		$l = $this->GetList($options);
		return $l->ItemCount();
	}	
		
/**
 * @param TListOptions $options
 * @return Iterator
 */
	public function GetList(TListOptions $options = null){
		if (count($options->Filter) > 0){
			if ($options->Filter[0] instanceof TCondition){
				if (($options->Filter[0]->Operands[0] == 'ClassName') && ($options->Filter[0]->Type == TConditionType::C_EQUAL)){
					if ($type = $this->TypesModel->GetItem($options->Filter[0]->Operands[1])){
						return new TArrayIterator($this->getAggregates($type));
					}
				}
			}
		}
		return new TArrayIterator(array());
	}
	
	protected function parseId($id,$get_base = true){
		$parts = explode('.',$id);
		if (count($parts) > 1){
			if ($type = $this->TypesModel->GetItem($parts[0])){
				if ($get_base)
					return array($type->Base,$parts[1]);
				return array($type,$parts[1]);
			}
		}
		return null;
	}
	
/**
 * @param string $id
 * @return IItem
 */
	public function GetItem($id){
		if ($data = $this->parseId($id,false))
			return $this->getAggregate($data[0], $data[1]);
		return null;
	}
		
/**
 * @param string $id
 * @return bool
 */
	public function DeleteItem($id){
		if ($data = $this->parseId($id,false)){
			$meta = $this->getRawAggregates($data[0]);
			unset($meta[$data[1]]);
			$this->setRawAggregates($data[0], $meta);
			$this->TypesModel->EditItem($data[0]->ItemId(), $this->editData($data[0]));	
		}
	}
	
/**
 * @param array $data
 * @return IItem
 */
	public function CreateItem(array $data, $class = null){
		if (isset($data["ClassName"])){
			if ($type = $this->TypesModel->GetItem($data["ClassName"])){
				$meta = $this->getRawAggregates($type);
				$nm = $this->TypesModel->FormPhpName($data["Caption"]);
				unset($data["ClassName"]);
				$meta[$nm] = $this->parseData($nm, $data);
				$this->setRawAggregates($type, $meta);
				$this->TypesModel->EditItem($type->ItemId(), $this->editData($type));
				return $this->GetItem($type->ItemId().'.'.$nm);
			} else throw new TExposableException('Type '.$data['ClassName'].' not found');
		}
	}
	
/**
 * @param string $id
 * @param $data
 * @return IItem
 */
	public function EditItem($id,array $data){
		if ($t = $this->parseId($id,false)){
			$meta = $this->getRawAggregates($t[0]);
			$meta[$t[1]] = (object)((array)$this->parseData($t[1], $data) + (array)$meta[$t[1]]);
			$this->setRawAggregates($t[0], $meta);
			$this->TypesModel->EditItem($t[0]->ItemId(), $this->editData($t[0]));
		}
		return $this->GetItem($id);
	}	
}